package com.seleniti.enpareja.android.model.integration.gcm;

import org.ioc.commons.flowcontrol.common.impl.ReceiverAdapter;
import org.ioc.commons.flowcontrol.logincontroller.LoginController;
import org.ioc.commons.flowcontrol.placecontroller.PlaceController;
import org.ioc.commons.impl.android.flowcontrol.placecontroller.AndroidPlaceController;
import org.ioc.commons.utils.Format;

import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Vibrator;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.TaskStackBuilder;
import android.util.Log;

import com.seleniti.enpareja.android.AppShellActivity;
import com.seleniti.enpareja.android.R;
import com.seleniti.enpareja.android.control.entrypoint.EnParejaAndroid;
import com.seleniti.enpareja.controller.common.domain.LoggedUserInfo;
import com.seleniti.enpareja.controller.control.controller.LoginFailedCause;
import com.seleniti.enpareja.controller.control.controller.LoginParams;
import com.seleniti.enpareja.controller.control.factory.ClientFactory;
import com.seleniti.enpareja.controller.control.place.EnParejaPlace;
import com.seleniti.enpareja.controller.model.integration.database.domain.Notification;
import com.seleniti.enpareja.controller.model.integration.gcm.Constants;
import com.seleniti.enpareja.controller.model.integration.service.EnParejaServiceManager;

public class ScheduledService extends IntentService {

	private ClientFactory clientFactory;
	private LoginController<LoggedUserInfo, LoginFailedCause, LoginParams, String> loginController;
	private PlaceController placeController;

	public ScheduledService() {
		super("enParejaScheduledService");
	}

	@Override
	public void onCreate() {
		super.onCreate();
		this.clientFactory = ((EnParejaAndroid) this.getApplication()).getClientFactory();
		this.loginController = clientFactory.getLoginController();
		this.placeController = clientFactory.getPlaceController().forThisObject(this);
	}

	@Override
	protected void onHandleIntent(Intent intent) {
		// Do something, fire a notification or whatever you want to do here
		Log.d("debug", "Ring Rind !");

		final String notificationId = intent.getStringExtra(Constants.NOTIFICATION_ID_KEY);
		final EnParejaServiceManager sm = clientFactory.getServiceManager();

		sm.serviceFactory().notificationService().find(notificationId).caller(this)
				.to(new ReceiverAdapter<Notification>() {

					@Override
					public void success(Notification result) {
						/*
						 * Notification has been read by the user
						 */
						sm.serviceFactory().notificationService().read(notificationId).caller(ScheduledService.this);

						makeVibration(ScheduledService.this);
						showNotification(result);

					}

				});

	}

	private void makeVibration(Context context) {
		// Get instance of Vibrator from current Context
		Vibrator v = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);

		// Vibrate for 30 milliseconds
		v.vibrate(30);
	}

	private void showNotification(Notification n) {
		// TODO: Icono en función del tipo
		NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);

		String coupleName = loginController.getLoggedUserInfo() != null
				&& loginController.getLoggedUserInfo().getCoupleName() != null
				&& !loginController.getLoggedUserInfo().getCoupleName().isEmpty() ? loginController.getLoggedUserInfo()
				.getCoupleName() : "Tu pareja";

		EnParejaPlace goTo = EnParejaPlace.Main;
		mBuilder.setSmallIcon(R.drawable.ic_launcher);

		switch (n.getType()) {
		case ASKING_FOR_GARAGE:
			mBuilder.setContentTitle(getString(R.string.is_the_garage_free));
			// TODO: Pregunta de si o no en la notificación
			goTo = EnParejaPlace.Garage;
			break;
		case GARAGE_IS_OCCUPIED_NOW:
			mBuilder.setContentTitle(Format.substitute(getString(R.string.has_occupied_the_garage), coupleName));
			goTo = EnParejaPlace.Garage;
			break;
		case GARAGE_IS_FREE_NOW:
			mBuilder.setContentTitle(Format.substitute(getString(R.string.has_left_the_garage), coupleName));
			goTo = EnParejaPlace.Garage;
			goTo = EnParejaPlace.Garage;
			break;
		case HOME_TASKS_CHANGED:
			mBuilder.setContentTitle(Format.substitute(getString(R.string.home_tasks_changed), coupleName));
			goTo = EnParejaPlace.HomeTasks;
			break;
		case SHOPPING_LIST_CHANGED:
			mBuilder.setContentTitle(getString(R.string.shopping_list_changed));
			goTo = EnParejaPlace.ShoppingList;
			break;
		case MAKE_HOMETASK:
			mBuilder.setContentTitle(getString(R.string.reminder));
			goTo = EnParejaPlace.HomeTasks;
			break;
		case MEALS_CHANGED:
			mBuilder.setContentTitle(getString(R.string.meals_changed));
			goTo = EnParejaPlace.Meals;
			break;
		case SHARED_EXPENSES_CHANGED:
			mBuilder.setContentTitle(getString(R.string.shared_expenses_changed));
			goTo = EnParejaPlace.SharedExpenses;
			break;
		case STORE_PRODUCTS_CHANGED:
			mBuilder.setContentTitle(getString(R.string.store_products_changed));
			goTo = EnParejaPlace.PendingShopping;
			break;
		case UNFREEZE_FOOD:
			mBuilder.setContentTitle(getString(R.string.reminder));
			goTo = EnParejaPlace.Meals;
			break;
		case WORK_SHIFTS_CHANGED:
			mBuilder.setContentTitle(getString(R.string.work_shifts_changed));
			goTo = EnParejaPlace.WorkShifts;
			break;
		case GOT_COUPLED:
			mBuilder.setContentTitle(Format.substitute(getString(R.string.nowYouAreCoupledWith), coupleName));
			goTo = EnParejaPlace.Main;
			break;
		case BROKE_UP:
			mBuilder.setContentTitle(Format.substitute(getString(R.string.nowYouAreNotCoupled), coupleName));
			goTo = EnParejaPlace.Main;
			break;
		default:
			mBuilder.setSmallIcon(R.drawable.ic_launcher);
			break;
		}

		if (n.getExtraInfo() != null) {
			mBuilder.setContentText(n.getExtraInfo());
		}

		mBuilder.setAutoCancel(true);
		Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
		mBuilder.setSound(alarmSound);

		Intent resultIntent = ((AndroidPlaceController) placeController).getPlaceAsIntent(goTo);
		resultIntent.setClass(this, AppShellActivity.class);
		resultIntent.setAction(Intent.ACTION_MAIN);
		resultIntent.addCategory(Intent.CATEGORY_LAUNCHER);
		resultIntent.putExtra(AppShellActivity.FORCE_REFRESH_KEY, true);

		// The stack builder object will contain an artificial back stack for
		// the
		// started Activity.
		// This ensures that navigating backward from the Activity leads out of
		// your application to the Home screen.
		TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
		// Adds the back stack for the Intent (but not the Intent itself)
		stackBuilder.addParentStack(AppShellActivity.class);
		// Adds the Intent that starts the Activity to the top of the stack
		stackBuilder.addNextIntent(resultIntent);

		PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

		mBuilder.setContentIntent(resultPendingIntent);

		NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		// mId allows you to update the notification later on.
		mNotificationManager.notify(n.getType().ordinal(), mBuilder.build());
	}
}